' Stephen Toub
' Coded and published in January 2007 issue of MSDN Magazine 
' http://msdn.microsoft.com/msdnmag/issues/07/01/PreviewHandlers/default.aspx


Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Data
Imports System.Windows.Forms
Imports System.Collections.Generic
Imports System.Runtime.InteropServices
Imports System.Globalization
Imports C4F.DevKit.PreviewHandler.PreviewHandlerFramework

Namespace C4F.DevKit.PreviewHandler.PreviewHandlers
    <PreviewHandler("MSDN Magazine CSV Preview Handler", ".csv", "{8CF7761A-E923-470c-926E-8440C06FA8FE}"), ProgId("C4F.DevKit.PreviewHandler.PreviewHandlers.CsvPreviewHandler"), Guid("47F228F7-5338-4bb4-AF7B-7B52278E1095"), ClassInterface(ClassInterfaceType.None), ComVisible(True)> _
    Public NotInheritable Class CsvPreviewHandler
        Inherits StreamBasedPreviewHandler
        Protected Overrides Function CreatePreviewHandlerControl() As PreviewHandlerControl
            Return New CsvPreviewHandlerControl()
        End Function

        Private NotInheritable Class CsvPreviewHandlerControl
            Inherits StreamBasedPreviewHandlerControl
            Public Overrides Sub Load(ByVal stream As Stream)
                Dim grid As DataGridView = New DataGridView()
                grid.DataSource = ParseCsv(stream)
                grid.ReadOnly = True
                grid.Dock = DockStyle.Fill
                grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
                Controls.Add(grid)
            End Sub

            Private Shared Function ParseCsv(ByVal stream As Stream) As DataTable
                Dim table As DataTable = New DataTable()
                table.Locale = CultureInfo.CurrentCulture
                If TypeOf stream Is FileStream Then
                    table.TableName = (CType(stream, FileStream)).Name
                Else
                    table.TableName = "CSV"
                End If

                Dim lines As List(Of String()) = New List(Of String())()
                Dim maxFields As Integer = 0

                Using reader As StreamReader = New StreamReader(stream)
                    Dim line As String
                    line = reader.ReadLine()
                    Do While line IsNot Nothing
                        line = line.Trim()
                        If line.Length > 0 Then
                            Dim parts As String() = line.Split(","c)
                            maxFields = Math.Max(maxFields, parts.Length)
                            lines.Add(parts)
                        End If
                        line = reader.ReadLine()
                    Loop
                End Using

                If lines.Count > 0 AndAlso maxFields > 0 Then
                    For i As Integer = 0 To maxFields - 1
                        table.Columns.Add("Column " & i)
                    Next i
                    For Each line As Object() In lines
                        table.Rows.Add(line)
                    Next line
                End If

                Return table
            End Function
        End Class
    End Class
End Namespace